/** https://mp.weixin.qq.com/s?__biz=MzU5NDM5MDg1Mw%3D%3D&chksm=fe00aea4c97727b2954b84c46883afec3435efd2c1332bbd3d54e9ea5c6ba75d1c090431d830&idx=1&lang=zh_CN&mid=2247488654&scene=21&sn=a4ba58c8e317bde53cd53827e5a90f59&token=1118798341#wechat_redirect
 * 
 * generator是什么
 * 1.ES6 提供的一种异步编程解决方案
 * 2. Generator 函数就是遍历器生成函数，因此可以把 Generator 赋值给对象的Symbol.iterator属性，从而使得该对象具有 Iterator 接口
 *    myIterable[Symbol.iterator] = function* ()
 * 
 * generator的作用
 * 1.async函数的基本原理。Generator 可以暂停函数执行，返回任意表达式的值。是实现状态机的最佳结构
 * 2.控制流管理
 * 3.利用 Generator 函数，可以在任意对象上部署 Iterator 接口。
 * 4.作为数据结构 
 * 
 * generator写法(生成的Iterator对象)
 * 一是，function关键字与函数名之间有一个星号；
 * 二是，函数体内部使用yield语句，定义不同的内部状态（yield在英语里的意思就是“产出”）
 * 
 * 特点：
 * 1、分段执行，可以暂停
 * 2、可以控制阶段和每个阶段的返回值
 * 3、可以知道是否执行到结尾
 * 
 * 注意：
 * 1.g()并不会执行g函数，返回的也不是函数运行结果，而是一个指向内部状态的指针对象，也就是迭代器对象（Iterator Object）
 * 2.分段执行。
 *    每次调用next方法，内部指针就从函数头部或上一次停下来的地方开始执行，直到遇到下一个yield语句（或return语句）为止。
 *    换言之，Generator函数是分段执行的，yield语句是暂停执行的标记，而next方法可以恢复执行。
 * 每调用一次Generator函数，就返回一个迭代器对象，代表Generator函数的内部指针。
 * 以后，每次调用迭代器对象的next方法，就会返回一个有着value和done两个属性的对象。
 * value属性表示当前的内部状态的值，是yield语句后面那个表达式的值；done属性是一个布尔值，表示是否遍历结束。
 * 3.yield语句只能用于function的作用域，如果function的内部还定义了其他的普通函数，则函数内部不允许使用yield语句。
 * 4.yield语句如果参与运算，必须用括号括起来。console.log(3 + (yield 4)); // 打印7
 * 5.next方法可以有参数————next方法参数的作用，是为上一个yield语句赋值。
 *    带参数跟不带参数的区别是:带参数的情况，首先第一步就是将上一个yield语句重置为参数值，然后再照常执行剩下的语句。
 *    总之，区别就是先有一步先重置值，接下来其他全都一样。
 *6.
 *
 *
 *    
 */
// 一些使用

// function* g() {
//   let o = 0
//   let a = yield o++
//   console.log('a:' + a);
//   let b = yield o++
// }
// let gen = g()
// console.log(gen.next());
// console.log(gen.next(11));

//斐波那契数列
function* fibonacci() {
  let [prev, curr] = [0, 1];
  for (;;) { // 这里请思考：为什么这个循环不设定结束条件？
    [prev, curr] = [curr, prev + curr];
    yield curr;
  }
}
for (let n of fibonacci()) {
  if (n > 1000) {
    break;
  }
  console.log(n);
}